package com.shanghe.house.job;

import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;

import com.shanghe.house.entity.Device;
import com.shanghe.house.entity.Timer;
import com.shanghe.house.service.DeviceService;
import com.shanghe.house.service.TimerService;
import com.shanghe.house.util.CronUtils;
import com.shanghe.house.util.TimeUtils;

@Component
public class DeviceTimerJob {
    private static final Logger log = LoggerFactory.getLogger(DeviceTimerJob.class);
    private final TimerService timerService;
    private final DeviceService deviceService;

    public DeviceTimerJob(TimerService timerService, DeviceService deviceService) {
        this.timerService = timerService;
        this.deviceService = deviceService;
    }

    @Scheduled(cron = "0 * * * * ?")
    @Transactional
    public void checkTimers() {
        try {
            List<Timer> timers = timerService.lambdaQuery()
                    .eq(Timer::getStatus, true)
                    .list();

            if (timers.isEmpty()) {
                return;
            }

            // 按设备分组，避免同一设备被多次更新
            Map<Long, Timer> deviceTimers = timers.stream()
                    .filter(timer -> {
                        try {
                            return CronUtils.shouldExecute(timer.getCronExpression());
                        } catch (Exception e) {
                            log.error("定时任务cron表达式解析失败: {}", timer.getName(), e);
                            return false;
                        }
                    })
                    .collect(Collectors.toMap(
                        Timer::getDeviceId,
                        timer -> timer,
                        (t1, t2) -> {
                            log.warn("设备 {} 存在多个定时任务，保留任务 {}", 
                                    t1.getDeviceId(), t1.getName());
                            return t1;
                        }
                    ));

            if (deviceTimers.isEmpty()) {
                return;
            }

            try {
                executeTimers(deviceTimers);
            } catch (Exception e) {
                log.error("批量执行定时任务失败", e);
                // 尝试逐个执行
                deviceTimers.values().forEach(this::executeSingleTimer);
            }
        } catch (Exception e) {
            log.error("定时任务检查失败", e);
        }
    }

    private void executeTimers(Map<Long, Timer> deviceTimers) {
        Map<Long, Boolean> deviceStatuses = deviceTimers.entrySet().stream()
                .collect(Collectors.toMap(
                    Map.Entry::getKey,
                    e -> e.getValue().getTargetStatus()
                ));
        
        deviceService.batchUpdateStatus(deviceStatuses);

        deviceTimers.values().forEach(timer -> {
            int minutes = TimeUtils.cronToMinutes(timer.getCronExpression());
            log.info("执行定时任务: {}, 设备: {}, 状态: {}, 执行间隔: {}分钟", 
                    timer.getName(), timer.getDeviceId(), 
                    timer.getTargetStatus(), minutes);
        });
    }

    private void executeSingleTimer(Timer timer) {
        try {
            deviceService.lambdaUpdate()
                    .set(Device::getStatus, timer.getTargetStatus())
                    .eq(Device::getId, timer.getDeviceId())
                    .update();
            
            int minutes = TimeUtils.cronToMinutes(timer.getCronExpression());
            log.info("单独执行定时任务: {}, 设备: {}, 状态: {}, 执行间隔: {}分钟", 
                    timer.getName(), timer.getDeviceId(), 
                    timer.getTargetStatus(), minutes);
        } catch (Exception e) {
            log.error("执行单个定时任务失败: {}", timer.getName(), e);
        }
    }
} 